package com.ruoyi.system.service.impl;

import java.io.InputStream;
import java.util.*;

import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.search.Hit;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.framework.config.ServerConfig;
import com.ruoyi.system.config.MinioConfig;
import com.ruoyi.system.constants.CommonConstants;
import com.ruoyi.system.domain.StandardNoEs;
import com.ruoyi.system.es.ESBuilder;
import com.ruoyi.system.es.ESContext;
import com.ruoyi.system.mapper.StandardNoEsMapper;
import com.ruoyi.system.service.IEsService;
import com.ruoyi.system.utils.Md5Utils;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.ByDb15Mapper;
import com.ruoyi.system.domain.ByDb15;
import com.ruoyi.system.service.IByDb15Service;
import org.springframework.web.multipart.MultipartFile;

/**
 * StandardService业务层处理
 * 
 * @author ruoyi
 * @date 2024-02-01
 */
@Service
@AllArgsConstructor
public class ByDb15ServiceImpl implements IByDb15Service
{

    private static final Logger log = LoggerFactory.getLogger(ByDb15ServiceImpl.class);

    @Autowired
    private ByDb15Mapper byDb15Mapper;

    @Autowired
    private ServerConfig serverConfig;

    @Autowired
    private StandardNoEsMapper standardNoEsMapper;


    @Autowired
    private MinioConfig minioConfig;

    @Autowired
    private MinioClient client;

    @Autowired
    private ESContext esContext;


    /**
     * 查询Standard
     * 
     * @param id Standard主键
     * @return Standard
     */
    @Override
    public ByDb15 selectByDb15ById(String id)
    {
        return byDb15Mapper.selectByDb15ById(id);
    }

    @Override
    public String getCal(String tableName) {
        log.info("--------------开始检测------------------");
        List<ByDb15> unSearchList = new ArrayList<>();
        //根据表名获取数据
        List<ByDb15> resultData = selectByCommonList(tableName);
        //循环数据查询
        for(ByDb15 byDb15:resultData){
            long res = searchA100(byDb15);
            if(res > 0L){

            }else{
                unSearchList.add(byDb15);
            }
        }
        //不存在的保存
        if(unSearchList.size() > 0){
            for(ByDb15 byDb15 : unSearchList){
                StandardNoEs standardNoEs = new StandardNoEs();
                standardNoEs.setId(byDb15.getId());
                standardNoEs.setA000(byDb15.getA000());
                standardNoEs.setA001(byDb15.getA001());
                standardNoEs.setA003(byDb15.getA003());
                standardNoEs.setA010(byDb15.getA010());
                standardNoEs.setA011(byDb15.getA011());
                standardNoEs.setA100(byDb15.getA100());
                standardNoEs.setA101(byDb15.getA101());
                standardNoEs.setA102(byDb15.getA102());
                standardNoEs.setA103(byDb15.getA103());
                standardNoEs.setA104(byDb15.getA104());
                standardNoEs.setA200(byDb15.getA200());
                standardNoEs.setA203(byDb15.getA203());
                standardNoEs.setA204(byDb15.getA204());
                standardNoEs.setA205(byDb15.getA205());
                standardNoEs.setA206(byDb15.getA206());
                standardNoEs.setA207(byDb15.getA207());
                standardNoEs.setA208(byDb15.getA208());
                standardNoEs.setA209(byDb15.getA209());
                standardNoEs.setA210(byDb15.getA210());
                standardNoEs.setA298(byDb15.getA298());
                standardNoEs.setA300(byDb15.getA300());
                standardNoEs.setA301(byDb15.getA301());
                standardNoEs.setA302(byDb15.getA302());
                standardNoEs.setA304(byDb15.getA304());
                standardNoEs.setA305(byDb15.getA305());
                standardNoEs.setA309(byDb15.getA309());
                standardNoEs.setA310(byDb15.getA310());
                standardNoEs.setA311(byDb15.getA311());
                standardNoEs.setA330(byDb15.getA330());
                standardNoEs.setA311(byDb15.getA311());
                standardNoEs.setA390(byDb15.getA390());
                standardNoEs.setA409(byDb15.getA409());
                standardNoEs.setA448(byDb15.getA448());
                standardNoEs.setA461(byDb15.getA461());
                standardNoEs.setA462(byDb15.getA462());
                standardNoEs.setA502(byDb15.getA502());
                standardNoEs.setA505(byDb15.getA505());
                standardNoEs.setA800(byDb15.getA800());
                standardNoEs.setA805(byDb15.getA805());
                standardNoEs.setA807(byDb15.getA807());
                standardNoEs.setA808(byDb15.getA808());
                standardNoEs.setA820(byDb15.getA820());
                standardNoEs.setA821(byDb15.getA821());
                standardNoEs.setA823(byDb15.getA823());
                standardNoEs.setA824(byDb15.getA824());
                standardNoEs.setA825(byDb15.getA825());
                standardNoEs.setA826(byDb15.getA826());
                standardNoEs.setA835(byDb15.getA835());
                standardNoEs.setA837(byDb15.getA837());
                standardNoEs.setA840(byDb15.getA840());
                standardNoEs.setA845(byDb15.getA845());
                standardNoEs.setA846(byDb15.getA846());
                standardNoEs.setA847(byDb15.getA847());
                standardNoEs.setA850(byDb15.getA850());
                standardNoEs.setA860(byDb15.getA860());
                standardNoEs.setA861(byDb15.getA861());
                standardNoEs.setA863(byDb15.getA863());
                standardNoEs.setA864(byDb15.getA864());
                standardNoEs.setA865(byDb15.getA865());
                standardNoEs.setA866(byDb15.getA866());
                standardNoEs.setA870(byDb15.getA870());
                standardNoEs.setA871(byDb15.getA871());
                standardNoEs.setA885(byDb15.getA885());
                standardNoEs.setA886(byDb15.getA886());
                standardNoEs.setA890(byDb15.getA890());
                standardNoEs.setA891(byDb15.getA891());
                standardNoEs.setA892(byDb15.getA892());
                standardNoEs.setA893(byDb15.getA893());
                standardNoEs.setA894(byDb15.getA894());
                standardNoEs.setA895(byDb15.getA895());
                standardNoEs.setReserveA(byDb15.getReserveA());
                standardNoEs.setReserveB(byDb15.getReserveB());
                standardNoEs.setReserveC(byDb15.getReserveC());
                standardNoEs.setReserveD(byDb15.getReserveD());
                standardNoEs.setReserveE(byDb15.getReserveE());
                standardNoEs.setFilePath(byDb15.getFilePath());
                standardNoEs.setTableName(tableName);

                standardNoEsMapper.insertStandardNoEs(standardNoEs);
            }

        }
        log.info("--------------结束检测------------------");
        return "成功";
    }

    @Override
    public String updateCal() {
        return null;
    }


    public Long searchA100(ByDb15 byDb15) {

        try {
            ESBuilder b = ESBuilder.builder().build();
            if (StringUtils.isNotNull(byDb15.getA100()) && StringUtils.isNotEmpty(byDb15.getA100())) {
                ESBuilder build = ESBuilder.builder().build();
                build.buildQueryMutiMath(CommonConstants.searchFieldA100, byDb15.getA100());
                b.buildBoolMust(build.getQuery());
            }

            List<String> indexList = new ArrayList<>();
            indexList.add(CommonConstants.INDEX_PREFIX);

            SearchResponse<Object> response = esContext.searchIndex(indexList, b, 0, 10, null, null);
            // 数据量太大 log.info("查询到结果:{}", response ==null?"":JSON.toJSONString(response.hits().hits().stream().map(Hit::source).collect(Collectors.toList())));
            return response == null ? 0 : response.hits().total().value();
        } catch (Exception e) {
            e.printStackTrace();
            return 0L;
        } finally {
//            try {
//                userService.saveUserBehaviorOfSearch(keyword);
//            } catch (Exception e) {
//            }
        }
    }

    /**
     * 查询Standard列表
     * 
     * @param byDb15 Standard
     * @return Standard
     */
    @Override
    public List<ByDb15> selectByDb15List(ByDb15 byDb15)
    {
        List<ByDb15> list = byDb15Mapper.selectByDb15List(byDb15);
        for(ByDb15 byDb151:list){
            if(StringUtils.isNotEmpty(byDb15.getA100())){
                String result = highLightContent(byDb151.getA100(),byDb15.getA100());
                byDb151.setA100(result);
            }
            if(StringUtils.isNotEmpty(byDb15.getA298())){
                String result = highLightContent(byDb151.getA298(),byDb15.getA298());
                byDb151.setA298(result);
            }
        }
        return list;
    }

    @Override
    public List<ByDb15> selectByCommonList(String tableName) {
        return byDb15Mapper.selectByCommonList(tableName);
    }


    public String highLightContent(String content,String keywords){
        int index = content.indexOf(keywords);
        List<Integer> matchPositions = new ArrayList<>();
        while(index >=0){
            matchPositions.add(index);
            index = content.indexOf(keywords,index+1);
        }
        String highlightedContent = content;
        for(int position: matchPositions){
            highlightedContent = highlightedContent.replaceFirst(keywords,"<span style=\"color:red;\">$0</span>");
        }
        //过滤img标签
        return highlightedContent;
    }


    /**
     * 搜索引擎搜索标准
     * @param byDb15 Standard
     * @return
     */
    @Override
    public List<ByDb15> selectStandardList(ByDb15 byDb15) {
        return byDb15Mapper.selectByDb15List(byDb15);
    }

    /**
     * 新增Standard
     * 
     * @param byDb15 Standard
     * @return 结果
     */
    @Override
    public int insertByDb15(ByDb15 byDb15)
    {
        byDb15.setId(UUID.randomUUID().toString());
        //添加es  a893
        try{
            Map<String, Object> doc = new HashMap<>();
            doc.put("id", byDb15.getId());
            doc.put("a000", byDb15.getA000());
            doc.put("a001", byDb15.getA001());
            doc.put("a003", byDb15.getA003());
            doc.put("a010", byDb15.getA010());
            doc.put("a011", byDb15.getA011());
            doc.put("a100", byDb15.getA100());
            doc.put("a101", byDb15.getA101());
            doc.put("a102", byDb15.getA102());
            doc.put("a103", byDb15.getA103());
            doc.put("a104", byDb15.getA104());
            doc.put("a200", byDb15.getA200());
            doc.put("a203", byDb15.getA203());
            doc.put("a204", byDb15.getA204());
            doc.put("a205", byDb15.getA205());
            doc.put("a206", byDb15.getA206());
            doc.put("a207", byDb15.getA207());
            doc.put("a208", byDb15.getA208());
            doc.put("a209", byDb15.getA209());
            doc.put("a210", byDb15.getA210());
            doc.put("a298", byDb15.getA298());
            doc.put("a300", byDb15.getA300());
            doc.put("a301", byDb15.getA301());
            doc.put("a302", byDb15.getA302());
            doc.put("a304", byDb15.getA304());
            doc.put("a305", byDb15.getA305());
            doc.put("a309", byDb15.getA309());
            doc.put("a310", byDb15.getA310());
            doc.put("a311", byDb15.getA311());
            doc.put("a330", byDb15.getA330());
            doc.put("a331", byDb15.getA331());
            doc.put("a390", byDb15.getA390());
            doc.put("a409", byDb15.getA409());
            doc.put("a448", byDb15.getA448());
            doc.put("a461", byDb15.getA461());
            doc.put("a462", byDb15.getA462());
            doc.put("a502", byDb15.getA502());
            doc.put("a505", byDb15.getA505());
            doc.put("a800", byDb15.getA800());
            doc.put("a805", byDb15.getA805());
            doc.put("a807", byDb15.getA807());
            doc.put("a808", byDb15.getA808());
            doc.put("a820", byDb15.getA820());
            doc.put("a821", byDb15.getA821());
            doc.put("a823", byDb15.getA823());
            doc.put("a824", byDb15.getA824());
            doc.put("a825", byDb15.getA825());
            doc.put("a826", byDb15.getA826());
            doc.put("a835", byDb15.getA835());
            doc.put("a840", byDb15.getA840());
            doc.put("a837", byDb15.getA837());
            doc.put("a845", byDb15.getA845());
            doc.put("a846", byDb15.getA846());
            doc.put("a847", byDb15.getA847());
            doc.put("a850", byDb15.getA850());
            doc.put("a860", byDb15.getA860());
            doc.put("a861", byDb15.getA861());
            doc.put("a863", byDb15.getA863());
            doc.put("a864", byDb15.getA864());
            doc.put("a865", byDb15.getA865());
            doc.put("a866", byDb15.getA866());
            doc.put("a870", byDb15.getA870());
            doc.put("a871", byDb15.getA871());
            doc.put("a885", byDb15.getA885());
            doc.put("a886", byDb15.getA886());
            doc.put("a890", byDb15.getA890());
            doc.put("a891", byDb15.getA891());
            doc.put("a892", byDb15.getA892());
            doc.put("a893", byDb15.getA893());
            doc.put("a894", byDb15.getA894());
            doc.put("a895", byDb15.getA895());
            doc.put("create_time", byDb15.getCreateTime());
            doc.put("textAddress", byDb15.getTextAddress());
            doc.put("filePath", byDb15.getFilePath());
            doc.put("reserve_a", byDb15.getReserveA());
            doc.put("reserve_b", byDb15.getReserveB());
            doc.put("reserve_c", byDb15.getReserveC());
            doc.put("reserve_d", byDb15.getReserveD());
            doc.put("reserve_e", byDb15.getReserveE());
            doc.put("table_name", byDb15.getTableName());
            esContext.addDocument(CommonConstants.INDEX_PREFIX, String.valueOf(byDb15.getId()), doc);
        }catch(Exception e){
            log.error("添加es异常——------------{}",e.getMessage());
        }
//        standardMapper.insert(byDb15);
        byDb15.setCreateTime(DateUtils.getNowDate());
        byDb15.setUpdateTime(DateUtils.getNowDate());
        byDb15.setCreateBy(SecurityUtils.getUserId());
        byDb15.setUpdateBy(SecurityUtils.getUserId());
        return byDb15Mapper.insertByDb15(byDb15);
    }

    /**
     * 修改Standard
     * 
     * @param byDb15 Standard
     * @return 结果
     */
    @Override
    public int updateByDb15(ByDb15 byDb15)
    {
        //es更新
//        standardMapper.updateById(byDb15);
        return byDb15Mapper.updateByDb15(byDb15);
    }

    @Override
    public int updateCommonFileByName(String tableName, String id, String realPath) {
        return byDb15Mapper.updateCommonFileByName(tableName,id,realPath);
    }

    @Override
    public int updateByDb15ByCommonTableName(String tableName, ByDb15 byDb15) {
        return byDb15Mapper.updateByDb15ByCommonTableName(tableName,byDb15);
    }

    /**
     * 批量删除Standard
     * 
     * @param ids 需要删除的Standard主键
     * @return 结果
     */
    @Override
    public int deleteByDb15ByIds(String[] ids)
    {
        //标准删除
        for(String id: ids){
            //获取es数据
            Map<String,Object> mapNew  = esContext.getDocument(CommonConstants.INDEX_PREFIX,id,Map.class);
            if(mapNew.get("table_name")!=null){
                //删除数据库
                String tableName = mapNew.get("table_name").toString();
                if(StringUtils.isNotEmpty(tableName)){
                    byDb15Mapper.deleteByDb15ByIdCommon(tableName,id);
                }
            }
            //删除es
            esContext.deleteDocumentById(CommonConstants.INDEX_PREFIX,id);
        }
        return 1;
    }

    /**
     * 删除Standard信息
     * 
     * @param id Standard主键
     * @return 结果
     */
    @Override
    public int deleteByDb15ById(String id)
    {
        return byDb15Mapper.deleteByDb15ById(id);
    }

    /**
     *
     * @param file
     * @return
     */
    @Override
    public AjaxResult upload(MultipartFile file) {
        try
        {
            // 上传文件路径
            String filePath = RuoYiConfig.getUploadPath();
            // 上传并返回新文件名称
            String fileName = FileUploadUtils.extractFilename(file);
            InputStream inputStream = file.getInputStream();
            InputStream md5Stream = file.getInputStream();
            String md5 = Md5Utils.getFileMD5(md5Stream);
            PutObjectArgs args = PutObjectArgs.builder()
                    .bucket(minioConfig.getBucketName())
                    .object(fileName)
                    .stream(inputStream, file.getSize(), -1)
                    .contentType(file.getContentType())
                    .build();
            client.putObject(args);
            inputStream.close();
            md5Stream.close();
            String url = minioConfig.getReturnUrl() + "/" + minioConfig.getBucketName() + "/" + fileName;
            log.info("upload->{} to {}", file.getOriginalFilename(), url);
            String[] result = new String[3];
            result[0] = url;
            result[1] = fileName;
            result[2] = md5;

            AjaxResult ajax = AjaxResult.success();
            ajax.put("url", url);
            ajax.put("fileName", fileName);
            ajax.put("newFileName", FileUtils.getName(fileName));
            ajax.put("originalFilename", file.getOriginalFilename());

            return ajax;
        }
        catch (Exception e)
        {
            return AjaxResult.error(e.getMessage());
        }
    }
}
